package com.xqq.juc;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;

public class CountDownLatchDebugger {

    public static void main(String[] args) throws Exception {
        // 创建CountDownLatch，初始计数为3
        CountDownLatch latch = new CountDownLatch(3);

        // 打印初始状态
        printLatchState(latch, "初始状态");

        // 创建3个工作线程
        for (int i = 1; i <= 3; i++) {
            new Thread(new Worker(i, latch), "Worker-" + i).start();
            Thread.sleep(500); // 确保线程按顺序启动
        }

        // 主线程等待所有工作完成
        System.out.println("\n主线程等待所有工作完成...");
        latch.await();
        System.out.println("\n所有工作已完成！主线程继续执行");

        // 打印最终状态
        printLatchState(latch, "最终状态");
    }

    static class Worker implements Runnable {
        private final int id;
        private final CountDownLatch latch;

        public Worker(int id, CountDownLatch latch) {
            this.id = id;
            this.latch = latch;
        }

        @Override
        public void run() {
            try {
                System.out.printf("\n[%s] 开始工作...\n", Thread.currentThread().getName());

                // 模拟工作时间
                int workTime = (int)(Math.random() * 3000) + 1000;
                Thread.sleep(workTime);

                System.out.printf("[%s] 工作完成 (耗时%dms)，准备减少计数\n",
                        Thread.currentThread().getName(), workTime);

                // 调试点1：countDown前
                printLatchState(latch, Thread.currentThread().getName() + " countDown前");

                // 减少计数
                latch.countDown();

                // 调试点2：countDown后
                printLatchState(latch, Thread.currentThread().getName() + " countDown后");

                // 工作完成后，线程继续执行其他任务
                Thread.sleep(1000);
                System.out.printf("[%s] 执行后续任务\n", Thread.currentThread().getName());

            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    // 打印CountDownLatch内部状态
    private static void printLatchState(CountDownLatch latch, String context) {
        try {
            // 使用反射获取内部Sync对象
            Field syncField = CountDownLatch.class.getDeclaredField("sync");
            syncField.setAccessible(true);
            AbstractQueuedSynchronizer sync = (AbstractQueuedSynchronizer) syncField.get(latch);

            // 获取state值（剩余计数）
            Field stateField = AbstractQueuedSynchronizer.class.getDeclaredField("state");
            stateField.setAccessible(true);
            int state = stateField.getInt(sync);

            // 获取等待队列信息
            Field headField = AbstractQueuedSynchronizer.class.getDeclaredField("head");
            headField.setAccessible(true);
            Object head = headField.get(sync);

            Field tailField = AbstractQueuedSynchronizer.class.getDeclaredField("tail");
            tailField.setAccessible(true);
            Object tail = tailField.get(sync);

            // 计算队列长度
            int queueLength = getQueueLength(head);

            System.out.printf("\n[%s] CountDownLatch状态 === 剩余计数: %d 等待队列长度: %d\n",
                    context, state, queueLength);

            // 打印队列详情
            if (queueLength > 0) {
                System.out.println("等待队列详情:");
                printQueue(head);
            }

        } catch (Exception e) {
            System.err.println("无法获取内部状态: " + e.getMessage());
        }
    }

    // 计算队列长度
    private static int getQueueLength(Object head) throws Exception {
        if (head == null) return 0;

        int count = 0;
        Object node = head;
        Class<?> nodeClass = Class.forName("java.util.concurrent.locks.AbstractQueuedSynchronizer$Node");
        Field nextField = nodeClass.getDeclaredField("next");
        nextField.setAccessible(true);

        while (node != null) {
            count++;
            node = nextField.get(node);
        }
        return count - 1; // 减去头节点
    }

    // 打印队列详情
    private static void printQueue(Object head) throws Exception {
        if (head == null) return;

        Class<?> nodeClass = Class.forName("java.util.concurrent.locks.AbstractQueuedSynchronizer$Node");
        Field nextField = nodeClass.getDeclaredField("next");
        Field threadField = nodeClass.getDeclaredField("thread");
        Field waitStatusField = nodeClass.getDeclaredField("waitStatus");

        nextField.setAccessible(true);
        threadField.setAccessible(true);
        waitStatusField.setAccessible(true);

        Object node = nextField.get(head); // 跳过头节点
        int index = 0;

        while (node != null) {
            Thread thread = (Thread) threadField.get(node);
            int waitStatus = waitStatusField.getInt(node);

            System.out.printf("  Node%d: 线程=%s 状态=%d (%s)\n",
                    index++,
                    thread != null ? thread.getName() : "null",
                    waitStatus,
                    waitStatusDescription(waitStatus));

            node = nextField.get(node);
        }
    }

    // 等待状态描述
    private static String waitStatusDescription(int status) {
        switch (status) {
            case -1: return "SIGNAL (等待被唤醒)";
            case -2: return "CONDITION (条件等待)";
            case -3: return "PROPAGATE (共享传播)";
            case  1: return "CANCELLED (已取消)";
            case  0: return "INITIAL (初始状态)";
            default: return "未知状态";
        }
    }
}
